/* 
 * File:   latticeutils.hpp
 * Author: mik
 *
 * Useful subroutines for manipulating lattices
 * 
 * Created on August 21, 2013, 10:40 PM
 */

#ifndef LATTICEUTILS_HPP
#define	LATTICEUTILS_HPP

#include <string.h>
#include "lattice.hpp"

class LatticeUtils {
public:

    /**
     * Copies lattices
     * @param slat source lattice
     * @param dlat destination lattice
     */
    static void copy(const Lattice* slat, Lattice* dlat) {
        memcpy((void*) dlat, (void*) slat, sizeof (Lattice));
    }

    /**
     * Scale lattice
     * @param scl three scaling factors
     * @param slat source lattice
     * @param dlat destination lattice
     */
    static void scale(double* scl, const Lattice* slat, Lattice* dlat) {
        for (int i = 0; i < slat->mNA; i++) {
            for (int j = 0; j < 3; j++) {
                dlat->mCoor[i][j] = slat->mCoor[i][j] * scl[j];
            }
        }
    }

    /**
     * Generic transformation
     * @param tr 3x3 transform matrix to be applied to each atom
     * @param slat source lattice
     * @param dlat destination lattice
     */
    static void transform(double* tr, const Lattice* slat, Lattice* dlat) {
        for (int i = 0; i < slat->mNA; i++) {
            for (int j = 0; j < 3; j++) {
                double v = 0;
                for (int k = 0; k < 3; k++)
                    v += tr[j * 3 + k] * slat->mCoor[i][k];
                dlat->mCoor[i][j] = v;
            }
        }

    }

    /**
     * Shifts internal atoms in a given direction
     * @param vec direction of shift
     * @param slat source lattice
     * @param dlat destination lattice
     */
    static void shiftInternal(double* vec, const Lattice* slat, Lattice* dlat) {
        for (int i = 0; i < slat->mNA; i++) {
            if (slat->mAttributes[i] == LATTICE_INTERNAL_ATOM) {
                for (int j = 0; j < 3; j++) {
                    dlat->mCoor[i][j] = slat->mCoor[i][j] + vec[j];
                }
            } else {
                for (int j = 0; j < 3; j++) {
                    dlat->mCoor[i][j] = slat->mCoor[i][j];
                }
            }
            //printf("INTERNAL\n");            
        }

    }
};

#endif	/* LATTICEUTILS_HPP */

